﻿namespace SharpF2.Components
{
	using System.Windows;
	using System.Windows.Controls.Primitives;
	using System.Windows.Input;
	using Commands;

	public static class FrameworkElementExtension
	{
		#region Public Attributes

		public static readonly DependencyProperty CloseCommandProperty =
			DependencyProperty.RegisterAttached("CloseCommand",
			                                    typeof (ICommand), typeof (FrameworkElementExtension),
			                                    new PropertyMetadata(new PropertyChangedCallback(OnCommandChanged)));

		public static readonly DependencyProperty DropCommandProperty =
			DependencyProperty.RegisterAttached("DropCommand",
			                                    typeof (DelegateCommand<DragEventArgs>),
			                                    typeof (FrameworkElementExtension),
			                                    new PropertyMetadata(new PropertyChangedCallback(OnDropCommandChanged)));

		#endregion

		#region Public Members

		public static ICommand GetCloseCommand(DependencyObject obj)
		{
			return obj.GetValue(CloseCommandProperty) as ICommand;
		}

		public static DelegateCommand<DragEventArgs> GetDropCommand(DependencyObject obj)
		{
			return obj.GetValue(DropCommandProperty) as DelegateCommand<DragEventArgs>;
		}

		public static void OnCommandChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
		{
			var b = o as ButtonBase;
			if (b == null) return;

			b.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler((sender, routedEventArgs) =>
			                                                           	{
			                                                           		var command = GetCloseCommand(sender as DependencyObject);
			                                                           		if (null != command)
			                                                           			command.Execute(null);

			                                                           		var window = GetWindow(sender as DependencyObject);
			                                                           		if (null != window)
			                                                           			window.Close();
			                                                           	}));
		}

		public static void OnDropCommandChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
		{
			var b = o as FrameworkElement;
			if (b == null) return;

			b.AddHandler(UIElement.DropEvent, new RoutedEventHandler((sender, routedEventArgs) =>
			                                                         	{
			                                                         		var args = routedEventArgs as DragEventArgs;
			                                                         		if (null == args) return;

			                                                         		var command = GetDropCommand(sender as DependencyObject);
			                                                         		if (null != command)
			                                                         			command.Execute(args);
			                                                         	}));
		}

		public static void SetCloseCommand(DependencyObject obj, ICommand value)
		{
			obj.SetValue(CloseCommandProperty, value);
		}

		public static void SetDropCommand(DependencyObject obj, DelegateCommand<DragEventArgs> value)
		{
			obj.SetValue(DropCommandProperty, value);
		}

		#endregion

		#region Private Members

		private static Window GetWindow(DependencyObject sender)
		{
			Window window = null;

			if (sender is Window)
				window = (Window) sender;

			if (window == null)
				window = Window.GetWindow(sender);

			return window;
		}

		#endregion
	}
}